package com.hm.common.plugin.network.netty;

import com.hm.common.autoconfigure.CommonProperties;
import com.hm.common.plugin.network.netty.su.WebSocketChildChannelHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.FixedRecvByteBufAllocator;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;

/**
 * @author shishun.wang
 * @version 1.0
 * @date 2019/4/11 11:28
 * @describe
 */
@Slf4j
public class NettyServerBootstrap {

	private CommonProperties commonProperties;
	
	public NettyServerBootstrap(CommonProperties commonProperties){
		this.commonProperties = commonProperties;
	}
	
	
	public void start() throws Exception{
		CommonProperties.Plugin.NettyConfig nettyConfig = commonProperties.getPlugin().getNetty();
		EventLoopGroup bossGroup = new NioEventLoopGroup(nettyConfig.getBossGroupCount());
		EventLoopGroup workerGroup = new NioEventLoopGroup(nettyConfig.getWorkerGroupCount());
		
		try{
			ServerBootstrap serverBootstrap = new ServerBootstrap();
			serverBootstrap.group(bossGroup, workerGroup)
					.channel(NioServerSocketChannel.class) //配置客户端的channel类型
					.option(ChannelOption.SO_BACKLOG, nettyConfig.getBacklog()) //配置TCP参数，握手字符串长度设置
					.option(ChannelOption.TCP_NODELAY, true) //TCP_NODELAY算法，尽可能发送大块数据，减少充斥的小块数据
					.childOption(ChannelOption.SO_KEEPALIVE, nettyConfig.isKeepAlive())//开启心跳包活机制，就是客户端、服务端建立连接处于ESTABLISHED状态，超过2小时没有交流，机制会被启动
					.childOption(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(592048))//配置固定长度接收缓存区分配器
					.childHandler(new WebSocketChildChannelHandler()); //绑定I/O事件的处理类,WebSocketChildChannelHandler中定义;
			
			log.info("WebsocketChatServer 启动了");
			// 绑定端口，开始接收进来的连接
			ChannelFuture f = serverBootstrap.bind(nettyConfig.getPort()).sync(); // (7)
			
			// 等待服务器  socket 关闭 。
			// 在这个例子中，这不会发生，但你可以优雅地关闭你的服务器。
			f.channel().closeFuture().sync();
		}finally {
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
			log.info("WebsocketChatServer 关闭了");
		}
	}
}
